package com.fast.fastenjoy.base.verify.mapping;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.persistence.Table;

import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSONObject;
import com.fast.fastenjoy.base.verify.exception.VerifyException;

/**
 * 
 * 验证实体实体映射类<br/>
 * 
 * <b>修改历史:</b> <br/>
 *  version 1.0.0 2014-5-29 chenliaohua create <br/>
 */
public class VerifyMapping {

	private static final Logger LOG = Logger.getLogger(VerifyMapping.class);
	
	private Class<? extends Object> clazz;
	private String tableName;
	private Map<String, VerifyFieldMapping> verifyFields;
	
	private static Map<String, VerifyMapping> CACHE = new HashMap<String, VerifyMapping>();
	
	public static VerifyMapping build(Class<? extends Object> clazz){
		
		if(clazz == null){
			return null;
		}
		
		VerifyMapping tm = null;
		
		String name = clazz.getName();
		
		if(CACHE.containsKey(name)){
			return CACHE.get(name);
		}
		
		try{
			Table table = clazz.getAnnotation(Table.class);
			tm  = new VerifyMapping(clazz);
			tm.tableName = table == null ? null : table.name();
			tm.verifyFields = VerifyFieldMapping.build(tm);
		}catch(Throwable e){
			LOG.debug("TableMapping.build error, message:" + e.getMessage());
			return null;
		}
		
		return tm;
	}
	
	/**
	 * 验证
	 * @param entityManager
	 * @throws VerifyException
	 */
	public void verify(VerifyObject verifyObject) throws VerifyException{
		
		StringBuffer msg = new StringBuffer();
		
		Iterator<String> iterator = verifyFields.keySet().iterator();
		while(iterator.hasNext()){
			
			String fieldName = iterator.next();
			
			VerifyFieldMapping tcm = verifyFields.get(fieldName);
			
			if(tcm == null){
				continue;
			}
			
			try{
				msg.append(tcm.verify(verifyObject));
			}catch(Throwable e){
				LOG.debug("TableMapping.verify[" + tcm + "]error, message:" + e.getMessage());
			}
		}
		
		if(msg.length() > 0){
			throw new VerifyException(msg.toString());
		}
	}
	
	private VerifyMapping(Class<? extends Object> clazz){
		this.clazz = clazz;
		CACHE.put(clazz.getName(), this);
	}
	
	public Class<? extends Object> getObjClass() {
		return clazz;
	}

	public Map<String, VerifyFieldMapping> getVerifyFields() {
		return verifyFields;
	}

	public String getTableName() {
		return tableName;
	}

	@Override
	public String toString() {
		return JSONObject.toJSONString(this);
	}
	
}
